package com.societyGames.codeAlong.state.codeExercise.view
{
import com.societyGames.codeAlong.state.codeExercise.model.testCase.TestCaseController;
import com.societyGames.flashForms.CenterScaleContainer;
import com.societyGames.flashForms.DirectContainer;
import com.societyGames.flashForms.FourStateButton;
import com.societyGames.flashForms.HorizontalTileContainer;
import com.societyGames.flashForms.ItemsContainer;
import com.societyGames.flashForms.basicSkin.BasicAssets;
import com.societyGames.system.EventObject;

import flash.display.Sprite;
import flash.events.Event;

public class ExecuteControl extends Sprite
{
  [Embed(source="/../assets/InterfaceAssets.swf", symbol="NextDisabled")]
  private static const _nextDisabledSpriteClass:Class;
  [Embed(source="/../assets/InterfaceAssets.swf", symbol="NextImage")]
  private static const _nextEnabledSpriteClass:Class;
  [Embed(source="/../assets/InterfaceAssets.swf", symbol="PlayDisabled")]
  private static const _playDisabledSpriteClass:Class;
  [Embed(source="/../assets/InterfaceAssets.swf", symbol="PlayImage")]
  private static const _playEnabledSpriteClass:Class;
  [Embed(source="/../assets/InterfaceAssets.swf", symbol="RewindDisabled")]
  private static const _rewindDisabledSpriteClass:Class;
  [Embed(source="/../assets/InterfaceAssets.swf", symbol="RewindImage")]
  private static const _rewindEnabledSpriteClass:Class;
  [Embed(source="/../assets/InterfaceAssets.swf", symbol="StopDisabled")]
  private static const _stopDisabledSpriteClass:Class;
  [Embed(source="/../assets/InterfaceAssets.swf", symbol="StopImage")]
  private static const _stopEnabledSpriteClass:Class;

  private var _testCaseController:TestCaseController;
  private var _horizontalTileContainer:HorizontalTileContainer;
  private var _resetButton:FourStateButton;
  private var _stopButton:FourStateButton;
  private var _playButton:FourStateButton;
  private var _nextButton:FourStateButton;
  private var _stopPlayContainer:DirectContainer;

  public function ExecuteControl()
  {
    _rewindClickEventObject = new EventObject(this, "REWIND");
    _stopClickEventObject = new EventObject(this, "STOP");
    _playClickEventObject = new EventObject(this, "PLAY");
    _nextClickEventObject = new EventObject(this, "NEXT");

    initializeInterface();
  }

  public function setTestCaseController(testCaseController:TestCaseController):void
  {
    clearTestCaseController();
    _testCaseController = testCaseController;
    if (_testCaseController != null)
    {
      _testCaseController.testCasesSucceededEventObject.addEventListener(testCasesSucceededHandler);
      _testCaseController.refreshControlsEventObject.addEventListener(refreshControlsHandler);
      refreshControlsHandler(null);
    }
  }

  public function testCasesSucceededHandler(event:Event):void
  {
    nextIsEnabled = true;
  }

  private function clearTestCaseController():void
  {
    if (_testCaseController != null)
    {
      _testCaseController.testCasesSucceededEventObject.removeEventListener(testCasesSucceededHandler);
      _testCaseController.refreshControlsEventObject.removeEventListener(refreshControlsHandler)
    }
  }

  private function refreshControlsHandler(event:Event):void
  {
    rewindIsEnabled = _testCaseController.canReset;
    playIsEnabled = _testCaseController.canExecute || _testCaseController.canReset;
    stopIsEnabled = _testCaseController.canStop;
    //Stop and play occupy the same space. Only show one of them.
    if (playIsEnabled)
    {
      _stopPlayContainer.item = _playButton;
    }
    else if (stopIsEnabled)
    {
      _stopPlayContainer.item = _stopButton;
    }
  }

  public override function set width(value:Number):void
  {
    this._horizontalTileContainer.width = value;
  }

  public override function set height(value:Number):void
  {
    this._horizontalTileContainer.height = value;
  }

  private var _rewindClickEventObject:EventObject;

  public function get rewindClickEventObject():EventObject
  {
    return this._rewindClickEventObject;
  }

  private var _stopClickEventObject:EventObject;

  public function get stopClickEventObject():EventObject
  {
    return this._stopClickEventObject;
  }

  private var _playClickEventObject:EventObject;

  public function get playClickEventObject():EventObject
  {
    return this._playClickEventObject;
  }

  private var _nextClickEventObject:EventObject;

  public function get nextClickEventObject():EventObject
  {
    return this._nextClickEventObject;
  }

  public function get rewindIsEnabled():Boolean
  {
    return this._resetButton.enabled;
  }

  public function set rewindIsEnabled(value:Boolean):void
  {
    this._resetButton.enabled = value;
  }

  public function get stopIsEnabled():Boolean
  {
    return this._stopButton.enabled;
  }

  public function set stopIsEnabled(value:Boolean):void
  {
    this._stopButton.enabled = value;
  }

  public function get playIsEnabled():Boolean
  {
    return this._playButton.enabled;
  }

  public function set playIsEnabled(value:Boolean):void
  {
    this._playButton.enabled = value;
  }

  public function get nextIsEnabled():Boolean
  {
    return this._nextButton.enabled;
  }

  public function set nextIsEnabled(value:Boolean):void
  {
    this._nextButton.enabled = value;
  }

  public function get runButton():FourStateButton
  {
    return this._playButton;
  }

  public function get resetButton():FourStateButton
  {
    return this._resetButton;
  }

  public function get stopButton():FourStateButton
  {
    return this._stopButton;
  }

  public function get nextButton():FourStateButton
  {
    return this._nextButton;
  }

  public function disable():void
  {
    this._resetButton.enabled = false;
    this._stopButton.enabled = false;
    this._playButton.enabled = false;
    this._nextButton.enabled = false;
  }

  public function initializeInterface():void
  {
    this._resetButton = createButton(rewindButtonClickHandler, ExecuteControl._rewindEnabledSpriteClass, ExecuteControl._rewindDisabledSpriteClass);
    this._stopButton = createButton(stopButtonClickHandler, ExecuteControl._stopEnabledSpriteClass, ExecuteControl._stopDisabledSpriteClass);
    this._playButton = createButton(playButtonClickHandler, ExecuteControl._playEnabledSpriteClass, ExecuteControl._playDisabledSpriteClass);
    this._nextButton = createButton(nextButtonClickHandler, ExecuteControl._nextEnabledSpriteClass, ExecuteControl._nextDisabledSpriteClass);

    this._stopPlayContainer = new DirectContainer();
    this._stopPlayContainer.item = this._playButton;

    this._horizontalTileContainer = new HorizontalTileContainer();
    this._horizontalTileContainer.addItem(_resetButton);
    this._horizontalTileContainer.addItem(_stopPlayContainer);
    this._horizontalTileContainer.addItem(_nextButton);
    this.addChild(this._horizontalTileContainer);
  }

  private function createButton(clickHandler:Function, enabledSpriteClass:Class, disabledSpriteClass:Class):FourStateButton
  {
    var inactive:Sprite = createButtonSprite(BasicAssets.DisabledButtonClass, disabledSpriteClass);
    var up:Sprite = createButtonSprite(BasicAssets.ButtonClass, enabledSpriteClass);
    var over:Sprite = createButtonSprite(BasicAssets.SelectedButtonClass, enabledSpriteClass);
    var down:Sprite = createButtonSprite(BasicAssets.DownButtonClass, enabledSpriteClass);
    var button:FourStateButton = new FourStateButton(inactive, up, over, down);
    button.buttonClickEventObject.addEventListener(clickHandler);
    return button;
  }

  private function createButtonSprite(buttonSpriteClass:Class, imageSpriteClass:Class):Sprite
  {
    var button:Sprite = new buttonSpriteClass();
    var imageContainer:CenterScaleContainer = new CenterScaleContainer();
    imageContainer.item = Sprite(new imageSpriteClass());
    var itemsContainer:ItemsContainer = new ItemsContainer();
    itemsContainer.addItem(button);
    itemsContainer.addItem(imageContainer);
    return itemsContainer;
  }

  private function rewindButtonClickHandler(event:Event):void
  {
    this._rewindClickEventObject.dispatchEvent();
  }

  private function stopButtonClickHandler(event:Event):void
  {
    this._stopClickEventObject.dispatchEvent();
  }

  private function playButtonClickHandler(event:Event):void
  {
    this._playClickEventObject.dispatchEvent();
  }

  private function nextButtonClickHandler(event:Event):void
  {
    this._nextClickEventObject.dispatchEvent();
  }
}
}